#include "struct.h"
#include "symbole.h"
#include "tabSymbole.h"
#include "instruction.h"
#include "arbre_evaluation.h"

extern FILE *yyin;

#define NB_LIGNES 10
#define NB_COL 10
#define MAX_FLEURS 10
#define MAX_CARNIVORES 10
/*nombre d'abeilles maximum par ruche*/
#define MAX_ABEILLES 10

/*servira a determiner le temps pendant lequel dormira un thread (en millisecondes)*/
#define TEMPS_SLEEP	99999
/*Plus la valeur est grande, moins il y aura de fourmis sur la grille*/
#define RAND_VAL_MAX	15

#define MAX_ENERGIE 10
#define MAX_NECTAR 10
#define INIT_NECTAR 50

#define COUT_ABEILLE 10
#define COUT_MIEL 10

#define ab 0
#define mi 1

// définir un tableau de fleur dont l'id est l'indice du tableau pour retrouver la fleur
// l'emplacement de la fleur est stockée dans la case
// permet de récupérer le nectar d'une fleur sans les coordonnées de la case

serveurAff_t serveurAff = {1, 0, 0, 0, PTHREAD_MUTEX_INITIALIZER,
							PTHREAD_COND_INITIALIZER,PTHREAD_COND_INITIALIZER};

case_t grille[NB_LIGNES][NB_COL];
fleur * fleurs[MAX_FLEURS];
carnivore * carnivores[MAX_CARNIVORES];
abeille * abeilles[MAX_ABEILLES*2];
ruche * ruches[2];
algo * list_algo;
int cptFleurs = 0;
int cptCarnivores = 0;
int nb_algo = 0;
int creation_thread = 0;
pthread_mutex_t mutex_creation_abeille = PTHREAD_MUTEX_INITIALIZER;


void case_ajoutAbeille(int x,int y,abeille * a){
	int tmp=x;
	x=y;
	y=tmp;
	printf("case_ajoutAbeille        element de la case : %d \n",grille[x][y].element);
	if(grille[x][y].element==GRILLE_VIDE){
		grille[x][y].element=GRILLE_ABEILLE;
	}
	liste_abeille * l =(liste_abeille *)malloc(sizeof(struct liste_abeille));
	l->suivante=(grille[x][y].liste_abeille);
	l->abeille=a;
	grille[x][y].liste_abeille=l;
	printf("case_ajoutAbeille termine        nouvel element de la case : %d\n",grille[x][y].element);	
	sleep(2);
}
void case_supprimerAbeille(int x,int y,abeille * a){
	int tmp=x;
	x=y;
	y=tmp;
	printf("case_supprimerAbeille element :%d\n",grille[x][y].element);
	int trouve=0;
	liste_abeille * l =(grille[x][y].liste_abeille);
	liste_abeille * temp =(grille[x][y].liste_abeille);
	if (grille[x][y].liste_abeille->abeille->num==a->num){
		trouve==1;
		l=grille[x][y].liste_abeille->suivante;
		free(grille[x][y].liste_abeille);
		grille[x][y].liste_abeille=l;
		if ((grille[x][y].liste_abeille)->abeille==NULL && grille[x][y].element==GRILLE_ABEILLE){
			grille[x][y].element=GRILLE_VIDE;
		}		
	}else {
	
		while(l->suivante!=NULL && trouve ==0){
			if (l->suivante->abeille->num==a->num){
				if (l->suivante->suivante==NULL){
					free(l->suivante);
					l->suivante=NULL;
					}
				else{
					temp=l->suivante->suivante;
					free(l->suivante);
					l->suivante=temp;
				}	
				trouve=1;
			}
			l=l->suivante;
		}
	}
	
	
}


/* Fonction permettant de créer une abeille
 * Elle prend en paramètre l'id de l'abeille, sa position X et Y
 * et le numéro de la ruche auquel elle doit appartenir
 */
abeille * creer_abeille(int id, int x, int y, int ruche) {
	
	abeille * a = (abeille *) malloc(sizeof(struct abeille));
	a->num = id;
	a->energie = MAX_ENERGIE;
	a->energiemax = (rand()%30)+10;
	a->nectar = 0;
	a->nectarmax = (rand()%10)+5;
	a->memx = 0;
	a->memy = 0;
	//position courante de l'abeille égale a la position de sa ruche
	a->posx = x;
	a->posy = y;
	a->num_ruche = ruche;
	a->ruchex = x;
	a->ruchey = y;
	a->duree_vie = (rand()%20)+10;
	a->vitesse = rand()%10;
	a->attaque = rand()%20;
	a->defense = rand()%25;
	a->thread=(pthread_t *)malloc(sizeof(pthread_t));
	int r = rand()%nb_algo;
	algo * temp = list_algo;
	while(r!=0) {
		temp=temp->suivant;
		r--;
	}
	a->algo = temp;
	abeilles[id]=a;
	printf("Création d'une abeille posx : %d, posy : %d\n",a->posx,a->posy);
	
	pthread_mutex_lock(& (grille[a->posx][a->posy].mutex));
	case_ajoutAbeille(a->posx,a->posy,a);
	pthread_mutex_unlock(& (grille[a->posx][a->posy].mutex));
	return a;	
	
}

void avancer(abeille * a){

	// verrouiller le case courante (bloquant)
		pthread_mutex_lock(& (grille[a->posx][a->posy].mutex));
		
		printf("avancer(a)\n");
		int n_x, n_y, a_x, a_y;
		int deplacement;
		a_x = a->posx;
		a_y = a->posy;
		
		// déplacement
		do {
			
			deplacement = rand() % 4;
			switch (deplacement) {
				case 0:
					// Gauche
					n_x = (a->posx)-1;
					n_y = a->posy;
					break;
				
				case 1:
					// Haut
					n_x = a->posx;
					n_y = a->posy-1;
					break;
				
				case 2:
					// Droite
					n_x = (a->posx)+1;
					n_y = a->posy;
					break;
				case 3:
					// Bas
					n_x = a->posx;
					n_y = (a->posy)+1;
					break;
				default:
					// Rien
					n_x = a->posx;
					n_y = a->posy;
					break;
			}
			printf("n_x : %d, n_y : %d\n",n_x,n_y);
		}while(n_x>=NB_COL || n_y>=NB_LIGNES || n_x<0 || n_y<0);
		
		printf("deplacement\n");
		
			
		pthread_mutex_lock(& (grille[n_x][n_y].mutex));
		// success
		switch (grille[n_x][n_y].element) {		
			case GRILLE_CARNIVORE:		
				// Déplacer l'abeille sur la case souhaitée
				case_ajoutAbeille(n_x,n_y,a);
				case_supprimerAbeille(n_x,n_y,a);
				
				a->posx = n_x;
				a->posy = n_y;
				
				
				
				break;
			default:	
				printf("default\n");	
				// Déplacer l'abeille sur la case souhaitée
				case_ajoutAbeille(n_x,n_y,a);
				case_supprimerAbeille(a->posx,a->posy,a);
				
				a->posx = n_x;
				a->posy = n_y;
				
				
				
				break;
			}		
			
		pthread_mutex_unlock(& (grille[n_x][n_y].mutex));
				
			
}




void exec_instruction(instruction * i,abeille * a) {
	//printf("\n\n------------- DEBUT PARCOURS ------------- \n");
	
	//printf("\n\n%d\n\n",i->suivante->suivante->suivante->type_instruction);
	
	while(i!=NULL) {
			//printf("BOUCLE :\n");
			//printf("%d\n\n",i->type_action_cond);
		
		switch(i->type_instruction){
			case INSCTRUCTION_ACTION :
				switch((int)i->s->valeur){
					case ACTION_BUTINER:
						printf("Butiner()\n");
						break;
					case ACTION_RECHARGER:
						printf("Recharger()\n");
						break;
					case ACTION_DECHARGER:
						printf("Decharger()\n");
						break;
					case ACTION_ATTAQUER:
						printf("Attaquer()\n");
						break;
					case ACTION_AVANCER:
						printf("Avancer()\n");
						avancer(a);
						pthread_mutex_lock(&serveurAff.mutex);
						while (!serveurAff.fin)
							pthread_cond_wait(&serveurAff.termine, &serveurAff.mutex);
						serveurAff.reqATraiter = 1;
						serveurAff.fin = 0;
						pthread_cond_signal(&serveurAff.requete);
						pthread_mutex_unlock(&serveurAff.mutex);
						sleep(1);
						break;
					case ACTION_DEPLACER:
						/*printf("Deplacer(");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						printf(",");
						affiche_arbre(i->condition2);
						printf("(%d)",evaluer_arbre(i->condition2));
						printf(")\n");*/
						break;
				}
				break;
				
			case INSCTRUCTION_VAR :
				/*printf("%s = ",i->s->nom);
				printf("%d",(int)i->s->valeur);
				//printf("%s=%d\n",i->s->nom,(int)i->s->valeur);
				//printf(i->s->nom);
				affiche_arbre(i->condition1);
				printf("(%d)",evaluer_arbre(i->condition1));
				printf("\n");*/
				break;
				
			case INSCTRUCTION_COND :
				/*switch(i->type_action_cond){
					case ACTION_COND_SI :
						printf("SI ");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						//printf("( %s %d)",i->condition1->n->fg->f->variable->nom,i->condition1->n->operateur);
						printf(" ALORS \n");
						exec_instruction(i->list1->suivante, a);
						//affiche_instruction(i->list1->suivante);
						printf("FIN SI\n");
						break;
						
					case ACTION_COND_SI_SINON :
						printf("SI ");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						printf(" ALORS \n");
						exec_instruction(i->list1->suivante, a);
						//affiche_instruction(i->list1->suivante);
						printf(" SINON \n");
						exec_instruction(i->list2->suivante, a);
						//affiche_instruction(i->list2->suivante);
						printf("FIN SI\n");
						break;
						
					case ACTION_COND_SI_SINON_SI :
						printf("SI ");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						printf(" ALORS \n");
						exec_instruction(i->list1->suivante, a);
						//affiche_instruction(i->list1->suivante);
						printf(" SINON SI\n");
						affiche_arbre(i->condition2);
						printf("(%d)",evaluer_arbre(i->condition2));
						printf(" ALORS \n");
						exec_instruction(i->list2->suivante, a);
						//affiche_instruction(i->list2->suivante);
						printf(" SINON \n");
						exec_instruction(i->list3->suivante, a);
						//affiche_instruction(i->list3->suivante);
						printf("FIN SI\n");
						break;
						
					case ACTION_COND_TANTQUE :
						printf("TANTQUE ");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						printf(" FAIRE \n");
						exec_instruction(i->list1->suivante, a);
						//affiche_instruction(i->list1->suivante);
						printf("FIN TANTQUE\n");
						break;
				}*/
				break;
				
			case INSCTRUCTION_FONCTION : 
				/*affiche_arbre(i->condition1);
				printf("(%d)",evaluer_arbre(i->condition1));*/
				break;
		}
	
	//printf("\n---TEST--%d-\n",i->type_instruction);
	
	//if(i->suivante!=NULL)
	i=i->suivante;
	//else
	//	break;
	
	}
}
void *routineAbeille(void *arg) {
	
	
	abeille * a = (abeille *) arg;
	printf("RoutineAbeille  posx : %d, posy : %d\n",a->posx,a->posy);
	symbole * s = (symbole *)rechercher(a->algo->ts,a->algo->nom);	
	while(1){
		
		exec_instruction(s->instruction->suivante,a);
		
		/*// vérouiller l'abeille courante
		pthread_mutex_lock(& (a->mutex));
			
		
		//affiche_instruction(s->instruction->suivante);
		
		pthread_mutex_lock(&serveurAff.mutex);
		while (!serveurAff.fin)
			pthread_cond_wait(&serveurAff.termine, &serveurAff.mutex);
		serveurAff.reqATraiter = 1;
		serveurAff.fin = 0;
		pthread_cond_signal(&serveurAff.requete);
		pthread_mutex_unlock(&serveurAff.mutex);
			
			
			
		// déverouiller l'abeille courante
		pthread_mutex_unlock(& (a->mutex));
			
		// autorise le cancel si le mutex est débloqué
		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
		pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
			
		pthread_testcancel();
		*/
		
	}
}


void *afficherGrille(void *arg) {
	int i, j;
	int fin = 0;
	//printf("afficherGRille");

	serveurAff.cptAbeilles = 0;
	while (!fin) {
		printf("afficherGRille\n");
		pthread_mutex_lock(&serveurAff.mutex);
		while (!serveurAff.reqATraiter)
			pthread_cond_wait(&serveurAff.requete, &serveurAff.mutex);

		for (i = 0; i < 5; i++)
			printf("\n");
		printf("Etape %d\n", serveurAff.noEtape);
		printf("Abeilles présentes : %d\n", serveurAff.cptAbeilles);
		printf("Fleurs présentes : %d\n", cptFleurs);
		printf("Plantes Carnivores présentes : %d\n", cptCarnivores);
		for (i = 0; i < NB_LIGNES; i++) {
			for (j = 0; j < (NB_COL * 7) + 1; j++)
				printf("-");
			printf("\n");

			for (j = 0; j < NB_COL; j++) {
				printf("|");
				printf(" ");
				switch (grille[i][j].element) {
					case GRILLE_VIDE:
						printf("    ");
						break;
					case GRILLE_FLEUR:
						printf(" Fl ");
						break;
					case GRILLE_CARNIVORE:
						printf(" Ca ");
						break;
					case GRILLE_ABEILLE:
						printf(" Ab ");
						break;
					case GRILLE_RUCHE:
						printf("#RA#");
						break;
					case GRILLE_RUCHEENNEMIE:
						printf("#RE#");
						break;
						
				}
				printf(" ");
			}
			printf("|\n");
		}
		for (i = 0; i < (NB_COL * 7) + 1; i++)
			printf("-");
		printf("\n");

		usleep(TEMPS_SLEEP);
		serveurAff.noEtape++;
		serveurAff.reqATraiter = 0;
			serveurAff.fin = 1;
		/*if (serveurAff.cptAbeilles == 1){
			fin = 1;
		}	
		else {
			serveurAff.reqATraiter = 0;
			serveurAff.fin = 1;
		}*/

		pthread_cond_broadcast(&serveurAff.termine);
		pthread_mutex_unlock(&serveurAff.mutex);
	}

	return NULL;
}



void initialiserGrille() {
	int randVal, randValx, randValy, cptAbeilles = 0;
	int statut,num_ruche = 0;
	int i, j, i2, j2,ii,jj;
	
	
     	

	


	for (i = 0; i < NB_LIGNES; i++) {
		for (j = 0; j < NB_COL; j++) {
			statut = pthread_mutex_init(&grille[i][j].mutex, NULL);
			grille[i][j].liste_abeille = (liste_abeille*)malloc(sizeof(liste_abeille));
			randVal = rand() % RAND_VAL_MAX;
			if (randVal > 3)
				randVal = 0;
			else if (randVal==3)
				randVal==1;
			switch (randVal) {
				case GRILLE_VIDE:
					grille[i][j].element = GRILLE_VIDE;
					break;
				case GRILLE_FLEUR:
					if(cptFleurs<MAX_FLEURS){
						grille[i][j].element = GRILLE_FLEUR;
						grille[i][j].fl = cptFleurs;
						fleur * f = (fleur *)malloc(sizeof(struct fleur));
						f->id = cptFleurs;
						f->nectar=100;
						f->estlibre=1;
						fleurs[cptFleurs] = f;
						cptFleurs++;
					}
					break;
				case GRILLE_CARNIVORE:
					if (cptCarnivores<MAX_CARNIVORES){
						grille[i][j].element = GRILLE_CARNIVORE;
						grille[i][j].car = cptCarnivores;
						carnivore * c = (carnivore *)malloc(sizeof(struct carnivore));
						c->id = cptCarnivores;
						carnivores[cptCarnivores] = c;
						cptCarnivores++;
					}
					break;
				/*case GRILLE_ABEILLE:
					grille[i][j].element = GRILLE_ABEILLE;
					abeille * a = creer_abeille(cptAbeilles,i,j,num_ruche);
					//printf("-----ALGO----\n%d\n%s\n--------\n",a->vitesse,a->algo->nom);

					grille[i][j].abeille = a;
					abeilles[cptAbeilles] = a;
					//grille[i][j].fourmi = &threadsFourmis[cptAbeilles];
					//coordGrille[cptAbeilles].x = i;
					//coordGrille[cptAbeilles].y = j;
					cptAbeilles++;
					if(num_ruche==0)
						num_ruche=1;
					else
						num_ruche=0;
					break;*/
			}
		}
	}
	
	//création des deux ruches
	
	//calcul distance entre les ruches
	i = rand()%NB_LIGNES;
	j = rand()%NB_COL;
	ii = rand()%NB_LIGNES;
	jj = rand()%NB_COL;
	printf("\n-------%d----------%d---------%d---------%d--------||||%d\n",i,j,ii,jj,(int)sqrt((i-ii)*(i-ii)+(j-jj)*(j-jj)));
	while ((int)sqrt((i-ii)*(i-ii)+(j-jj)*(j-jj))<5 || grille[i][j].element!=GRILLE_VIDE || grille[ii][jj].element!=GRILLE_VIDE){
		i = rand()%NB_LIGNES;
		j = rand()%NB_COL;
		ii = rand()%NB_LIGNES;
		jj = rand()%NB_COL;
		printf("\n------%d----------%d---------%d---------%d--------||||%d\n",i,j,ii,jj,(int)sqrt((i-ii)*(i-ii)+(j-jj)*(j-jj)));
	}
	
	
	ruche * ra=(ruche*) malloc (sizeof(struct ruche));
	ra->posx=j;
	ra->posy=i;
	ra->qte_nectar=INIT_NECTAR;
	ra->qte_miel=0;
	ra->num_ruche=0;
	ra->qte_abeilles=0;
	ra->thread=(pthread_t *)malloc(sizeof(pthread_t));
	ruches[0]=ra;
	
	grille[i][j].element = GRILLE_RUCHE;
	
	ruche * re=(ruche*) malloc (sizeof(struct ruche));
	re->posx=jj;
	re->posy=ii;
	re->qte_nectar=INIT_NECTAR;
	re->qte_miel=0;
	re->qte_abeilles=0;
	re->num_ruche=1;
	re->thread=(pthread_t *)malloc(sizeof(pthread_t));
	ruches[1]=re;
	
	grille[ii][jj].element = GRILLE_RUCHEENNEMIE;
	printf("----X : %d -----\n",j);
	printf("----Y : %d -----\n",i);
	printf("----XX : %d -----\n",jj);
	printf("----YY : %d -----\n",ii);

}

void affiche_instruction(instruction * i) {
	//printf("\n\n------------- DEBUT PARCOURS ------------- \n");
	
	//printf("\n\n%d\n\n",i->suivante->suivante->suivante->type_instruction);
	
	while(i!=NULL) {
			//printf("BOUCLE :\n");
			//printf("%d\n\n",i->type_action_cond);
		
		switch(i->type_instruction){
			case INSCTRUCTION_ACTION :
				switch((int)i->s->valeur){
					case ACTION_BUTINER:
						printf("Butiner()\n");
						break;
					case ACTION_RECHARGER:
						printf("Recharger()\n");
						break;
					case ACTION_DECHARGER:
						printf("Decharger()\n");
						break;
					case ACTION_ATTAQUER:
						printf("Attaquer()\n");
						break;
					case ACTION_AVANCER:
						printf("Avancer()\n");
						break;
					case ACTION_DEPLACER:
						printf("Deplacer(");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						printf(",");
						affiche_arbre(i->condition2);
						printf("(%d)",evaluer_arbre(i->condition2));
						printf(")\n");
						break;
				}
				break;
				
			case INSCTRUCTION_VAR :
				printf("%s = ",i->s->nom);
				//printf("%d",(int)i->s->valeur);
				//printf("%s=%d\n",i->s->nom,(int)i->s->valeur);
				//printf(i->s->nom);
				affiche_arbre(i->condition1);
				printf("(%d)",evaluer_arbre(i->condition1));
				printf("\n");
				break;
				
			case INSCTRUCTION_COND :
				switch(i->type_action_cond){
					case ACTION_COND_SI :
						printf("SI ");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						//printf("( %s %d)",i->condition1->n->fg->f->variable->nom,i->condition1->n->operateur);
						printf(" ALORS \n");
						affiche_instruction(i->list1->suivante);
						printf("FIN SI\n");
						break;
						
					case ACTION_COND_SI_SINON :
						printf("SI ");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						printf(" ALORS \n");
						affiche_instruction(i->list1->suivante);
						printf(" SINON \n");
						affiche_instruction(i->list2->suivante);
						printf("FIN SI\n");
						break;
						
					case ACTION_COND_SI_SINON_SI :
						printf("SI ");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						printf(" ALORS \n");
						affiche_instruction(i->list1->suivante);
						printf(" SINON SI\n");
						affiche_arbre(i->condition2);
						printf("(%d)",evaluer_arbre(i->condition2));
						printf(" ALORS \n");
						affiche_instruction(i->list2->suivante);
						printf(" SINON \n");
						affiche_instruction(i->list3->suivante);
						printf("FIN SI\n");
						break;
						
					case ACTION_COND_TANTQUE :
						printf("TANTQUE ");
						affiche_arbre(i->condition1);
						printf("(%d)",evaluer_arbre(i->condition1));
						printf(" FAIRE \n");
						instruction * temp = (instruction *)malloc(sizeof(struct instruction));
						//temp = i->list1->suivante;
						affiche_instruction(i->list1->suivante);
						printf("FIN TANTQUE\n");
						break;
				}
				break;
				
			case INSCTRUCTION_FONCTION : 
				affiche_arbre(i->condition1);
				printf("(%d)",evaluer_arbre(i->condition1));
				break;
		}
	
	//printf("\n---TEST--%d-\n",i->type_instruction);
	
	//if(i->suivante!=NULL)
	i=i->suivante;
	//else
	//	break;
	
	}
}


void *routineRuche(void * arg) {
	
	int * id=(int *) arg;
	int statut; 
	int * id_ab;
	while (1){
		ruche  r = *ruches[*id];
		int statut = pthread_mutex_trylock(&r.mutex);
		if (statut==0){
			
			printf("Routine Ruche %d\n",r.num_ruche);
			int abeilleOuMiel=ab;
			while ((r.qte_abeilles==0 && r.qte_nectar>10) || r.qte_abeilles>0){
		
				if(r.qte_nectar>=10){
					if (abeilleOuMiel==ab){
						/*si on a pas attein le nombre maxi d'abeilles*/
						if (r.qte_abeilles<MAX_ABEILLES){
							/*on crée une abeille*/
							pthread_mutex_lock(&mutex_creation_abeille);
							int i=0,trouve=0;
							while(i<MAX_ABEILLES*2 && trouve==0){
								if(abeilles[i]==NULL){
									trouve=i;
								}
								i++;
							}
							printf("Création abeille dans routineRuche %d,%d,%d,%d\n",trouve, r.posx,r.posy, r.num_ruche);
							abeille * a = (abeille *)creer_abeille(trouve, r.posx,r.posy, r.num_ruche);
					
							statut = pthread_create(a->thread, NULL, routineAbeille,a);
					
							r.qte_abeilles++;
							r.qte_nectar=r.qte_nectar - COUT_ABEILLE;
					
							pthread_mutex_lock(&serveurAff.mutex);
							serveurAff.cptAbeilles++;	
					
							while (!serveurAff.fin)
								pthread_cond_wait(&serveurAff.termine, &serveurAff.mutex);
							serveurAff.reqATraiter = 1;
							serveurAff.fin = 0;
							pthread_cond_signal(&serveurAff.requete);
							pthread_mutex_unlock(&serveurAff.mutex);
					
							pthread_mutex_unlock(&mutex_creation_abeille);
					
					
					
								
						}	
						abeilleOuMiel=mi;	
					}
					else {
						/*on crée du miel*/
						r.qte_miel++;
						r.qte_nectar=r.qte_nectar - COUT_MIEL;
						abeilleOuMiel=ab;
					}
				}
				/*on attend un peu*/
				sleep(1);
		
		
			}
			pthread_mutex_unlock(&r.mutex);
		}
	}
}


int main(int argc, char *argv[]) {
	srand(time(NULL));
	
	list_algo = (algo *)malloc(sizeof(struct algo));
	
	printf("-------------------------------------\n");
	printf("-----------------DEBUT---------------\n");
	printf("-------------------------------------\n");
	
	
	 yyin = fopen( argv[1], "r" );
     yyparse();
     printf("---");
     fclose(yyin);
     
     algo * temp = list_algo;
     while(temp->suivant!=NULL){
     	nb_algo++;
     	temp = temp->suivant;
     }
     
     
     
     int cptAbeilles, i,j;
	pthread_t threadAff;
	 int statut;
     initialiserGrille();
     for (i = 0; i < NB_LIGNES; i++) {
		for (j = 0; j < NB_COL; j++) {
			printf("%d, ",grille[i][j].element);
		}
		printf("\n");
	}
     int * id;
     statut = pthread_create(&threadAff, NULL, afficherGrille, NULL);
     while (!serveurAff.fin)
		pthread_cond_wait(&serveurAff.termine, &serveurAff.mutex);
	serveurAff.reqATraiter = 1;
	serveurAff.fin = 0;
	pthread_cond_signal(&serveurAff.requete);
	pthread_mutex_unlock(&serveurAff.mutex);
     
     sleep(1);
     for (i=0;i<2;i++){
     	id=(int*)malloc (sizeof(int));
     	*id=i;
     	statut = pthread_create(ruches[i]->thread, NULL, routineRuche,id);
     }
     
     pthread_mutex_lock(&serveurAff.mutex);
		while (!serveurAff.fin)
			pthread_cond_wait(&serveurAff.termine, &serveurAff.mutex);
		serveurAff.reqATraiter = 1;
		serveurAff.fin = 0;
		pthread_cond_signal(&serveurAff.requete);
		pthread_mutex_unlock(&serveurAff.mutex);
		
     
     creation_thread = 1;
     
     //pthread_join(threadAff, NULL);
     for (i=0;i<2;i++){
     	pthread_join(*(ruches[i]->thread), NULL);
     }
     
     /*
     algo * temp = list_algo;
     int i = 1;
     int j =1;
     
     while(temp->suivant!=NULL){
     	
     	printf("\n\n\n -------------%d------------ \n\n",i);
     	afficher(temp->ts);
     	
     	symbole * s = rechercher(temp->ts,temp->nom);
     	
     	printf("---SYMBOLE ALGO---\n");
		printf("Symbole %s (%d) \n",s->nom, s->type);
		
		instruction * in = (instruction *) s->instruction;
		printf("\n\n------------- DEBUT PARCOURS ------------- \n");
		affiche_instruction(in->suivante);
		printf("\n\n------------- FIN PARCOURS ------------- \n");
		
		//in = in->suivante;
		
		/*while(in->suivante!=NULL){
			printf("---INSTRUCTION-%d--\n",j);
			printf("Instruction 1 : %d\n",in->type_instruction);
			
			
			if(in->type_instruction==1) {
			printf("Variable %s \n", in->s->nom);
			printf("Valeur %d \n", evaluer_arbre(in->condition1));
			}
			if(in->type_instruction==3) {
			printf("Condition %d \n", in->type_action_cond);
			
			printf("insctruction de la condition %d \n", in->list1->type_instruction);
			printf("insctruction de la condition %d \n", in->list1->suivante->type_instruction);
			
			
			
			
		}
		in = in->suivante;
		j++;
		}
		
				printf("---INSTRUCTION-%d--\n",j);
		printf("Instruction 1 : %d\n",in->type_instruction);
		if(in->type_instruction==1) {
		printf("Variable %s \n", in->s->nom);
		printf("Valeur %d \n", evaluer_arbre(in->condition1));
		}
		if(in->type_instruction==3) {
		printf("Condition %d \n", in->type_action_cond);
		
		
		//printf("insctruction de la condition %d \n", in->list1->type_instruction);
		printf("insctruction de la condition %d \n", in->list1->suivante->type_instruction);
		printf("Variable %s \n", in->list1->suivante->s->nom);
		printf("Valeur %d \n", evaluer_arbre(in->list1->suivante->condition1));
		printf("insctruction de la condition %d \n", in->list1->suivante->suivante->type_instruction);
		printf("Variable %s \n", in->list1->suivante->suivante->list1->suivante->s->nom);
		//printf("Valeur %d \n", evaluer_arbre(in->list1->suivante->suivante->list1->condition1));
			
			
		}
     	*//*
     	temp = temp->suivant;	
     	i++;
     	*/
    // }
     
     //afficher(list_algo->ts);
     
	
	//yyparse();
	
	/*symbole * s[10];
	
	initTab(s);
	
	symbole * u = (symbole *) malloc(sizeof(struct symbole));
	u->nom = "toto";
	
	symbole * t = (symbole *) malloc(sizeof(struct symbole));
	t->nom = "otto";
	
	inserer(s,u);
	afficher(s);
	inserer(s,t);
	
	afficher(s);
	
	
	
	symbole * r = rechercher(s, "tata");
	
	printf("--------------------\n");
	if(r!=NULL)
		printf("%s", r->nom);
	
	int i;
	printf("-----TEST-----\n");
	
	for(i=0;i<10;i++){
		printf("Iteration %d :\n",i);
		printf(trs[i]->valeur);
		printf("\n");
		
	}*/
	//printf("---FIN---\n");
	
	//free(list_algo);	
	
	
	sleep(5);
	
	return 0;
	
}
